package com.xjrsoft.module.customerTwo.EMP.checkin_log.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xjrsoft.common.Enum.GenderEnum;
import com.xjrsoft.common.page.PageOutput;
import com.xjrsoft.common.page.ConventPage;

import java.util.*;
import java.util.stream.Collectors;
import java.io.File;

import com.xjrsoft.core.tool.utils.CollectionUtil;
import com.xjrsoft.core.tool.utils.IoUtil;
import com.xjrsoft.common.utils.DataTransUtil;
import com.xjrsoft.common.result.Response;
import com.xjrsoft.core.constant.RedisKeyConstants;
import com.xjrsoft.core.tool.utils.BeanUtil;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.dto.TElectricCheckinItemsDto;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.dto.TElectricCheckinLogDto;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.dto.SaveTElectricCheckinLogFormDataDto;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.entity.TElectricCheckinItems;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.vo.TElectricCheckinItemsVo;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.vo.TElectricCheckinLogFormDataVo;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.vo.TElectricCheckinLogVo;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.vo.TElectricCheckinLogListVo;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.dto.TElectricCheckinLogListDto;
import com.xjrsoft.module.customerTwo.EMP.dormitory_room.entity.TDormitoryRoom;
import com.xjrsoft.module.customerTwo.EMP.dormitory_room.service.ITDormitoryRoomService;
import com.xjrsoft.module.customerTwo.EMP.settlement.dto.TElectricCheckoutSettlementToolsDto;
import com.xjrsoft.module.customerTwo.EMP.settlement.entity.TElectricCheckoutSettlementTools;
import com.xjrsoft.module.customerTwo.EMP.settlement.vo.TElectricCheckoutSettlementDetailsVo;
import com.xjrsoft.module.excel.entity.XjrExcelImport;
import com.xjrsoft.module.excel.factory.ParserFactory;
import com.xjrsoft.module.excel.parser.ImportDataParser;
import com.xjrsoft.module.excel.service.IXjrExcelImportService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.entity.TElectricCheckinLog;
import com.xjrsoft.module.customerTwo.EMP.checkin_log.service.ITElectricCheckinLogService;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

/**
 *  控制器
 *
 * @author lisen
 * @since 2023-07-21
 */
@Slf4j
@RestController
@AllArgsConstructor
@RequestMapping("/checkin_log")
@Api(value = "入住登记", tags = "入住登记接口")
public class TElectricCheckinLogController {


	private final ITElectricCheckinLogService tElectricCheckinLogService;

	private final ITDormitoryRoomService itDormitoryRoomService;

	@Resource
	IXjrExcelImportService importService;
	@Resource
	RedisTemplate<String,Object> redisTemplate;
	/**
	 * 详情 [{fieldName=department, lazyType=department}]
	 */
	@GetMapping("/updateRedis")
	public Response updateRedis(){
		return Response.ok(tElectricCheckinLogService.updateRedis());
	}

	@GetMapping("/id/{id}")
	@ApiOperation(value = "详情", notes = "传入id")
	@SaCheckPermission(value = {"checkin_log:view", "checkin_log:modify"}, mode = SaMode.OR)
	public Response<TElectricCheckinLogFormDataVo> getFormData(@PathVariable String id) {
		// 主表数据
		TElectricCheckinLogFormDataVo formDataVo = new TElectricCheckinLogFormDataVo();
		TElectricCheckinLog tElectricCheckinLog = tElectricCheckinLogService.getInfoById(id);
		TElectricCheckinLogVo tElectricCheckinLogVo = BeanUtil.copy(tElectricCheckinLog, TElectricCheckinLogVo.class);
		tElectricCheckinLogVo.setGender("未定义");
		if(tElectricCheckinLog.getGender()!=null){
			if(tElectricCheckinLog.getGender().equals(1)){
				tElectricCheckinLogVo.setGender("女");
			} else{
				tElectricCheckinLogVo.setGender("男");
			}
		}
		tElectricCheckinLogVo.setDepartmentName(DataTransUtil.getDepartmentNameById(tElectricCheckinLogVo.getDepartment()));
		formDataVo.setTElectricCheckinLogVo(tElectricCheckinLogVo);

		List<TElectricCheckinItemsVo> tElectricCheckinItemsVoList = BeanUtil.copyList(tElectricCheckinLogService.getTElectricCheckinItemsByParentId(id), TElectricCheckinItemsVo.class);
		formDataVo.setTElectricCheckinItemsVoList(tElectricCheckinItemsVoList);
		return Response.ok(formDataVo);
	}

	/**
	 * 自定义分页 
	 */
	@GetMapping
	@ApiOperation(value = "分页", notes = "传入tElectricCheckinLog")
	public Response<PageOutput<TElectricCheckinLogListVo>> getPageList(TElectricCheckinLogListDto listDto) {
		IPage<TElectricCheckinLog> page = tElectricCheckinLogService.getPageList(listDto);
		List<TElectricCheckinLog> records = BeanUtil.copyList(page.getRecords(), TElectricCheckinLog.class);
			// 转换列表数据
		List<TElectricCheckinLogListVo> voList = BeanUtil.copyListProperties(records, TElectricCheckinLogListVo::new, (tElectricCheckinLog, tElectricCheckinLogListVo) ->{
			// 这里可以定义特定的转换规则
			tElectricCheckinLogListVo.setGender(GenderEnum.getDescByCode(tElectricCheckinLog.getGender()==null?0:tElectricCheckinLog.getGender()).getDesc());
		});
		DataTransUtil.transListShowData(voList);
		return Response.ok(ConventPage.getPageOutput(page.getTotal(), voList));
	}

	/**
	 * 新增 
	 */
	@PostMapping
	@ApiOperation(value = "新增", notes = "传入tElectricCheckinLog")
	@SaCheckPermission("checkin_log:add")
	public Response save(@RequestBody @Valid SaveTElectricCheckinLogFormDataDto formDto) throws Exception {
		ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();

		TElectricCheckinLogDto tElectricCheckinLogDto = formDto.getTElectricCheckinLogDto();
		TElectricCheckinLog tElectricCheckinLog = BeanUtil.copy(tElectricCheckinLogDto, TElectricCheckinLog.class);

		List<TElectricCheckinItemsDto> tElectricCheckinItemsDtoList = formDto.getTElectricCheckinItemsDto();
		List<TElectricCheckinItems> tElectricCheckinItemsList = BeanUtil.copyList(tElectricCheckinItemsDtoList, TElectricCheckinItems.class);

		if(valueOperations.get(RedisKeyConstants.CACHE_ROOM_LEFT+tElectricCheckinLog.getRoomNumber())==null){
			TDormitoryRoom romm = itDormitoryRoomService.getByRoomNumber(tElectricCheckinLog.getRoomNumber());
			if(romm.getRoomType().equals("4")&&romm.getUsedBedNumber()<2){
				boolean isSuccess = tElectricCheckinLogService.add(tElectricCheckinLog,tElectricCheckinItemsList);
				return Response.status(isSuccess);
			}
		}
		if(Objects.nonNull(valueOperations.get(RedisKeyConstants.CACHE_ROOM_LEFT+tElectricCheckinLog.getRoomNumber()))|| tElectricCheckinLog.getIsCheckout().equals(1)){
			boolean isSuccess = tElectricCheckinLogService.add(tElectricCheckinLog,tElectricCheckinItemsList);
			return Response.status(isSuccess);
		}
		return Response.notOk("无剩余床位");
	}

	@PostMapping("/confirm/{id}")
	@ApiOperation(value = "确认", notes = "传入id")
	@SaCheckPermission("checkin_log:lock")
	public Response confirm(@PathVariable String id) {
		return Response.status(tElectricCheckinLogService.confirm(id));
	}
	/**
	 * 修改 
	 */
	@PutMapping("/id/{id}")
	@ApiOperation(value = "修改", notes = "传入tElectricCheckinLog")
	@SaCheckPermission("checkin_log:modify")
	public Response update(@PathVariable String id, @RequestBody SaveTElectricCheckinLogFormDataDto formDto) throws Exception {
		TElectricCheckinLogDto tElectricCheckinLogDto = formDto.getTElectricCheckinLogDto();
		TElectricCheckinLog tElectricCheckinLog = BeanUtil.copy(tElectricCheckinLogDto, TElectricCheckinLog.class);

		List<TElectricCheckinItemsDto> tElectricCheckinItemsDtoList = formDto.getTElectricCheckinItemsDto();
		List<TElectricCheckinItems> tElectricCheckinItemsList = BeanUtil.copyList(tElectricCheckinItemsDtoList, TElectricCheckinItems.class);

		return Response.status(tElectricCheckinLogService.update(id, tElectricCheckinLog,tElectricCheckinItemsList));
	}



	/**
	 * 删除 
	 */
	@DeleteMapping("/{ids}")
	@ApiOperation(value = "删除", notes = "传入ids")
	@SaCheckPermission(value = {"checkin_log:batchDelete", "checkin_log:delete"}, mode = SaMode.OR)
	public Response remove(@ApiParam(value = "主键集合", required = true) @PathVariable String ids) {
		return Response.status(tElectricCheckinLogService.delete(ids));
	}

	@PostMapping("/import")
	@ApiOperation(value = "excel批量导入数据", notes = "传入菜单id")
	@SaCheckPermission("checkin_log:import")
	public Response importData(@RequestParam("F_ModuleId") String moduleId, MultipartFile file) {
		XjrExcelImport excelImport = importService.getByModuleId(moduleId);
		ImportDataParser parser = ParserFactory.getImportDataParser();
		File excelFile = IoUtil.toFile(file);
		List<Map<String, Object>> recordList = parser.parseDataToMap(excelImport, excelFile);
		if (CollectionUtil.isNotEmpty(recordList)) {
			List<TElectricCheckinLogDto> entityDtoList = recordList.stream().map(record ->
					BeanUtil.toDtoBean(record, TElectricCheckinLogDto.class)
			).collect(Collectors.toList());
			List<TElectricCheckinLog> entities = BeanUtil.copyList(entityDtoList, TElectricCheckinLog.class);
			List<TElectricCheckinLog> removeList = new ArrayList<>();
			entities.stream().forEach(o -> {
				if(o.getIdentifyId().isEmpty() || o.getRoomNumber().isEmpty()) {
					removeList.add(o);
				}
			});
			entities.removeAll(removeList);
			Set<String> identifyId = new HashSet<String>();
			Set<String> repeatId = new HashSet<>();
			//检查是否有重复的人员
			for (TElectricCheckinLog checkinLoglog:
				 entities) {
				if(!identifyId.add(checkinLoglog.getIdentifyId())){
					repeatId.add(checkinLoglog.getIdentifyId());
					log.info("导入的人员中有重复"+repeatId);
				}
				identifyId.add(checkinLoglog.getIdentifyId());
			}
//			if(repeatId.size()>0){
//				return Response.notOk(repeatId,"导入的人员中有重复");
//			}
			//检查和库中入住的员工有无重复
			Set<String> repeatId2 = new HashSet<>();
			List<TElectricCheckinLog> baseCheck = tElectricCheckinLogService.checkinLogList();
			for (TElectricCheckinLog checkLog:
					baseCheck) {
				identifyId.forEach(i->{
					if(i.equals(checkLog.getIdentifyId())){
						repeatId2.add((i));
					}
				});
			}
			List<TElectricCheckinLog> removeList2 = new ArrayList<>();
			if(repeatId2.size()>0){
				for (TElectricCheckinLog base:
						baseCheck) {
					for(TElectricCheckinLog checkinLog:entities){
						if(checkinLog.getIdentifyId().equals(base.getIdentifyId())&&checkinLog.getRoomNumber().equals(base.getRoomNumber())) {
							log.info("导入人员和已经存在的人员重复"+checkinLog.getIdentifyId());
							removeList2.add(checkinLog);
						}
					}
				}
				//return Response.notOk(repeatId2,"导入人员和已经存在的人员重复");
			}
			entities.removeAll(removeList2);
			HashSet<String> info = tElectricCheckinLogService.branchImport(entities);
			if(!info.isEmpty()){
				return Response.notOk(info,"房间没有足够床位或没有该房间");
			}
			return Response.ok();
		}
		return Response.notOk("没有发现可用数据");
	}
}
